package com.zhanghe.study.proxy.javassist;

import javassist.*;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Test {
    public static void main(String[] args) throws CannotCompileException, NotFoundException, IOException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        // 创建ClassPool
        ClassPool classPool = ClassPool.getDefault();
        // 生成类com.zhanghe.study.Gen
        CtClass ctClass = classPool.makeClass("com.zhanghe.study.Gen");
        StringBuffer body = null;
        // 创建字段，指定字段类型、名称、所属类
        CtField ctField = new CtField(classPool.get("java.lang.String"),"prop",ctClass);
        // 设置为私有属性
        ctField.setModifiers(Modifier.PRIVATE);
        // 添加属性
        ctClass.addField(ctField);
        //getter/setter方法
        ctClass.addMethod(CtNewMethod.getter("getProp",ctField));
        ctClass.addMethod(CtNewMethod.setter("setProp",ctField));
        // 创建execute方法  方法返回值、方法名称、方法入参。方法所属类
        CtMethod ctMethod = new CtMethod(CtClass.voidType,"execute",new CtClass[]{},ctClass);
        ctMethod.setModifiers(Modifier.PUBLIC);

        body = new StringBuffer();
        body.append("\n System.out.println(\"execute()方法执行\");");
        body.append("\n");
        // 设置方法体
        ctMethod.setBody(body.toString());
        ctClass.addMethod(ctMethod);
        // 将类保存到文件中
        ctClass.writeFile("./target/classes");

        Class clazz = ctClass.toClass();
        Object obj = clazz.newInstance();
        Method method = obj.getClass().getMethod("setProp",String.class);
        method.invoke(obj,"测试");

        Method getMethod = obj.getClass().getMethod("getProp");
        System.out.println(getMethod.invoke(obj));

        Method exeMethod = obj.getClass().getMethod("execute");
        exeMethod.invoke(obj);
    }
}
